using B.S.XZYData.Api.Read.Application.Command.DefectiveSummary;
using B.S.XZYData.Api.Read.DTO;
using B.S.XZYData.Domain.ZSH;
using B.S.XZYData.ErrorCode;
using B.S.XZYData.Infrastructure;
using MediatR;
using Microsoft.Extensions.Logging;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using SqlSugar;

namespace B.S.XZYData.Api.Read.Application.Handler.DefectiveSummary
{
    /// <summary>
    /// 导出不良品汇总处理器
    /// </summary>
    public class ExportDefectiveSummaryHandler : IRequestHandler<ExportDefectiveSummaryCommand, ApiResult<byte[]>>
    {
        private readonly MyDbContext _context;
        private readonly ILogger<ExportDefectiveSummaryHandler> _logger;

        public ExportDefectiveSummaryHandler(
            MyDbContext context,
            ILogger<ExportDefectiveSummaryHandler> logger)
        {
            _context = context;
            _logger = logger;
        }

        public async Task<ApiResult<byte[]>> Handle(ExportDefectiveSummaryCommand request, CancellationToken cancellationToken)
        {
            try
            {
                // 使用与GetDefectiveSummaryHandler相同的查询逻辑
                var query = _context.WorkReport
                    .Where(wr => !wr.IsDeleted)
                    .WhereIF(!string.IsNullOrEmpty(request.WorkOrderCode), wr => wr.WorkOrderCode.Contains(request.WorkOrderCode!))
                    .WhereIF(!string.IsNullOrEmpty(request.ProductCode), wr => wr.ProductCode.Contains(request.ProductCode!))
                    .WhereIF(!string.IsNullOrEmpty(request.ProductName), wr => wr.ProductName.Contains(request.ProductName!))
                    .WhereIF(!string.IsNullOrEmpty(request.ProcessName), wr => wr.ProcessName.Contains(request.ProcessName!))
                    .WhereIF(!string.IsNullOrEmpty(request.Producer), wr => wr.Producer.Contains(request.Producer!))
                    .WhereIF(request.ProductionStartTimeBegin.HasValue, wr => wr.StartTime >= request.ProductionStartTimeBegin!.Value)
                    .WhereIF(request.ProductionStartTimeEnd.HasValue, wr => wr.StartTime <= request.ProductionStartTimeEnd!.Value)
                    .WhereIF(request.ProductionEndTimeBegin.HasValue, wr => wr.EndTime >= request.ProductionEndTimeBegin!.Value)
                    .WhereIF(request.ProductionEndTimeEnd.HasValue, wr => wr.EndTime <= request.ProductionEndTimeEnd!.Value)
                    .WhereIF(request.ReportQuantityMin.HasValue, wr => wr.ReportQty >= request.ReportQuantityMin!.Value)
                    .WhereIF(request.ReportQuantityMax.HasValue, wr => wr.ReportQty <= request.ReportQuantityMax!.Value)
                    .WhereIF(request.QualifiedQuantityMin.HasValue, wr => wr.GoodQty >= request.QualifiedQuantityMin!.Value)
                    .WhereIF(request.QualifiedQuantityMax.HasValue, wr => wr.GoodQty <= request.QualifiedQuantityMax!.Value);

                // 获取所有数据（不分页）
                var workReports = await query
                    .OrderBy(wr => wr.StartTime, OrderByType.Desc)
                    .ToListAsync();

                // 获取对应的不良品明细
                var workReportIds = workReports.Select(wr => wr.Id).ToList();
                var defectiveItems = await _context.WorkReportDefectiveItem
                    .Where(di => workReportIds.Contains(di.WorkReportId) && !di.IsDeleted)
                    .LeftJoin<Defective>((di, d) => di.DefectiveCode == d.DefectiveCode && !d.IsDeleted)
                    .Select((di, d) => new { di.WorkReportId, DefectiveName = d.DefectiveName ?? di.DefectiveCode })
                    .ToListAsync();

                // 转换为DTO列表
                var summaryData = workReports.Select(wr => new DefectiveSummaryDto
                {
                    Id = wr.Id,
                    WorkOrderCode = wr.WorkOrderCode,
                    ProductCode = wr.ProductCode,
                    ProductName = wr.ProductName ?? "",
                    ProcessCode = "", 
                    ProcessName = wr.ProcessName,
                    Producer = wr.Producer,
                    ProductionStartTime = wr.StartTime,
                    ProductionEndTime = wr.EndTime,
                    DefectiveItem = string.Join(",", defectiveItems.Where(di => di.WorkReportId == wr.Id).Select(di => di.DefectiveName)),
                    ProcessPlanQuantity = 0,
                    ReportQuantity = wr.ReportQty,
                    QualifiedQuantity = wr.GoodQty,
                    DefectiveQuantity = wr.DefectiveQty,
                    DefectiveRate = wr.ReportQty > 0 ? (decimal)wr.DefectiveQty / wr.ReportQty * 100 : 0,
                    CreateTime = wr.StartTime
                }).ToList();

                // 创建Excel文件
                var workbook = new XSSFWorkbook();
                var sheet = workbook.CreateSheet("不良品汇总");

                // 创建标题行
                var headerRow = sheet.CreateRow(0);
                var headers = new[]
                {
                    "工单编号", "产品编号", "产品名称", "工序名称", "生产人员",
                    "生产开始时间", "生产结束时间", "不良品项", "报工数量",
                    "合格数量", "不良数量", "不良率(%)", "创建时间"
                };

                // 创建标题样式
                var headerStyle = workbook.CreateCellStyle();
                headerStyle.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Grey25Percent.Index;
                headerStyle.FillPattern = FillPattern.SolidForeground;
                var headerFont = workbook.CreateFont();
                headerFont.IsBold = true;
                headerStyle.SetFont(headerFont);

                for (int i = 0; i < headers.Length; i++)
                {
                    var cell = headerRow.CreateCell(i);
                    cell.SetCellValue(headers[i]);
                    cell.CellStyle = headerStyle;
                }

                // 填充数据
                for (int i = 0; i < summaryData.Count; i++)
                {
                    var row = sheet.CreateRow(i + 1);
                    var item = summaryData[i];

                    row.CreateCell(0).SetCellValue(item.WorkOrderCode);
                    row.CreateCell(1).SetCellValue(item.ProductCode);
                    row.CreateCell(2).SetCellValue(item.ProductName);
                    row.CreateCell(3).SetCellValue(item.ProcessName);
                    row.CreateCell(4).SetCellValue(item.Producer);
                    row.CreateCell(5).SetCellValue(item.ProductionStartTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "");
                    row.CreateCell(6).SetCellValue(item.ProductionEndTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "");
                    row.CreateCell(7).SetCellValue(item.DefectiveItem);
                    row.CreateCell(8).SetCellValue(item.ReportQuantity);
                    row.CreateCell(9).SetCellValue(item.QualifiedQuantity);
                    row.CreateCell(10).SetCellValue(item.DefectiveQuantity);
                    row.CreateCell(11).SetCellValue(item.DefectiveRate.ToString("F2"));
                    row.CreateCell(12).SetCellValue(item.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"));
                }

                // 自动调整列宽
                for (int i = 0; i < headers.Length; i++)
                {
                    sheet.AutoSizeColumn(i);
                }

                // 将workbook转换为字节数组
                using var stream = new MemoryStream();
                workbook.Write(stream);
                var fileBytes = stream.ToArray();

                _logger.LogInformation($"成功导出不良品汇总数据，共 {summaryData.Count} 条记录");

                return new ApiResult<byte[]>
                {
                    Code = ApiEnum.Success,
                    Msg = "导出成功",
                    Data = fileBytes
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "导出不良品汇总数据时发生错误");
                return new ApiResult<byte[]>
                {
                    Code = ApiEnum.Error,
                    Msg = $"导出失败：{ex.Message}",
                    Data = null
                };
            }
        }
    }
} 